package com.example.app.wss;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wangzhuangzhuang
 * @DESC:
 * @date 2022-02-11 11:05
 */
@Component
@Slf4j
@ServerEndpoint(value = "/ws/asset")
public class WebSocketServer {

	// 统计连接客户端数量
	private static final AtomicInteger onlineCount = new AtomicInteger(0);
	// concurrent包的线程安全Set，用来存放每个客户端对应的Session对象
	private static CopyOnWriteArraySet<Session> sessionSet = new CopyOnWriteArraySet<>();

	/**
	 * 连接建立成功调用的方法
	 */
	@OnOpen
	public void onOpen(Session session) throws IOException {
		sessionSet.add(session);
		int countOfCurrentUser = onlineCount.incrementAndGet(); // 在线人数 +1
		log.info("有新连接加入，当前连接数为： {}", countOfCurrentUser);
	}

	/**
	 * 收到客户端消息后调用的方法
	 * @param message 客户端发送的消息
	 * */
	@OnMessage
	public void onMessage(String message, Session session) throws IOException{
		log.info("来自客户端的消息： {}", message);
		sendMessage(session, "Echo消息内容： " + message);
		// broadCastInfo(message); 群发消息
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose(Session session) {
		sessionSet.remove(session);
		int cnt = onlineCount.decrementAndGet();
		log.info("有连接关闭，当前连接数为：{}", cnt);
	}

	/**
	 * 出现错误
	 */
	@OnError
	public void onError(Session session, Throwable error) {
		log.error("发生错误：{}，Session ID： {}",error.getMessage(),session.getId());
	}


	/**
	 * 发送消息，实践表明，每次浏览器刷新，session会发生变化
	 *
	 * @param session session
	 * @param message 消息
	 */
	private static void sendMessage(Session session, String message) throws IOException {
		session.getBasicRemote().sendText(String.format("%s (From Server，Session ID=%s)", message, session.getId()));
	}

	/**
	 * 群发消息
	 *
	 * @param message 消息
	 */
	public static void broadCastInfo(String message) throws IOException {
		for (Session session : sessionSet) {
			if (session.isOpen()) {
				sendMessage(session, message);
			}
		}
	}
}